﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Xml;

namespace Aribaccio
{
    /// <summary>
    /// 公共类库
    /// XML文件操作类
    /// </summary>
    public class XmlReadWrite
    {
        /// <summary>
        /// 写入XML文件
        /// </summary>
        /// <param name="argInnerXml">XML文件字符串</param>
        /// <param name="argFileFullPathName">文件绝对全路径名称（可带后缀）</param>
        /// <returns>返回[null],表示写入成功</returns>
        public string WriteXmlFile(string argInnerXml, string argFileFullPathName)
        {
            if (string.IsNullOrWhiteSpace(argInnerXml)) { return "文件不能为空"; }
            try
            {
                string strExtensionName = Path.GetExtension(argFileFullPathName);
                if (!strExtensionName.EndsWith("xml", StringComparison.OrdinalIgnoreCase))
                {
                    argFileFullPathName = string.Concat(argFileFullPathName, ".xml");
                }
                string? strFileFullPath = Path.GetDirectoryName(argFileFullPathName);
                if (string.IsNullOrEmpty(strFileFullPath)) return string.Empty;
                //务器端没有找到有效的保存路径，创建
                if (!Directory.Exists(strFileFullPath))
                {
                    Directory.CreateDirectory(strFileFullPath);
                }
                XmlDocument doc = new XmlDocument();
                if (!string.IsNullOrWhiteSpace(argFileFullPathName) && !string.IsNullOrWhiteSpace(argInnerXml))
                {
                    doc.InnerXml = argInnerXml;
                    doc.Save(argFileFullPathName);
                }
                return string.Empty;
            }
            catch (Exception ep)
            {
                return "写入XML文件异常：" + ep.Message;
            }
        }

        /// <summary>
        /// 写入XML文件
        /// </summary>
        /// <param name="argInnerXml">XML文件字符串</param>
        /// <param name="argFileFullPathName">文件绝对全路径名称（可带后缀）</param>
        /// <returns>返回[null],表示写入成功</returns>
        public string WriteXmlFileStream(string argInnerXml, string argFileFullPathName)
        {
            if (string.IsNullOrWhiteSpace(argInnerXml)) { return "文件不能为空"; }
            try
            {
                string strExtensionName = Path.GetExtension(argFileFullPathName);
                if (!strExtensionName.EndsWith("xml", StringComparison.OrdinalIgnoreCase))
                {
                    argFileFullPathName = string.Concat(argFileFullPathName, ".xml");
                }
                string? strFileFullPath = Path.GetDirectoryName(argFileFullPathName);
                if (string.IsNullOrEmpty(strFileFullPath)) return string.Empty;
                //务器端没有找到有效的保存路径，创建
                if (!Directory.Exists(strFileFullPath))
                {
                    Directory.CreateDirectory(strFileFullPath);
                }
                XmlDocument doc = new XmlDocument();
                FileStream stream = new FileStream(argFileFullPathName, FileMode.OpenOrCreate, FileAccess.Write);
                if (stream != null && !string.IsNullOrWhiteSpace(argFileFullPathName) && !string.IsNullOrWhiteSpace(argInnerXml))
                {
                    doc.InnerXml = argInnerXml;
                    doc.Save(stream);
                }
                stream?.Close();
                stream?.Dispose();
                return string.Empty;
            }
            catch (Exception ep)
            {
                return "写入XML文件异常：" + ep.Message;
            }
        }

        /// <summary>
        /// 写入XML文件
        /// </summary>
        /// <typeparam name="T">泛型类</typeparam>
        /// <param name="argXmlItem">XML存储对象</param>
        /// <param name="argFileFullPathName">文件绝对全路径名称（可带后缀）</param>
        /// <returns>返回[null],表示写入成功</returns>
        public string WriteXmlFileStream<T>(T argXmlItem, string argFileFullPathName)
        {
            if (argXmlItem == null) { return "文件不能为空"; }
            try
            {
                string strExtensionName = Path.GetExtension(argFileFullPathName);
                if (!strExtensionName.EndsWith("xml", StringComparison.OrdinalIgnoreCase))
                {
                    argFileFullPathName = string.Concat(argFileFullPathName, ".xml");
                }
                string? strFileFullPath = Path.GetDirectoryName(argFileFullPathName);
                if (string.IsNullOrEmpty(strFileFullPath)) return string.Empty;
                //务器端没有找到有效的保存路径，创建
                if (!Directory.Exists(strFileFullPath))
                {
                    Directory.CreateDirectory(strFileFullPath);
                }
                //FileStream writeStream = new FileStream(strPathFileName, FileMode.Create);
                FileStream WriteStream = new FileStream(argFileFullPathName, FileMode.OpenOrCreate, FileAccess.Write);
                if (WriteStream != null)
                {
                    XmlSerializer serializer = new XmlSerializer(argXmlItem.GetType()); //xml对象
                    if (serializer != null)
                    {
                        serializer.Serialize(WriteStream, argXmlItem);
                    }
                    WriteStream.Close();
                    WriteStream.Dispose();
                }               
                return string.Empty;
            }
            catch (Exception ep)
            {
                return "写入XML文件异常：" + ep.Message;
            }
        }

        /// <summary>
        /// 读取XML文件
        /// </summary>
        /// <param name="argFileFullPathName">文件绝对全路径名称（可带后缀）</param>
        /// <param name="argErrorMsg">失败，返回异常信息</param>
        /// <returns>XML字符串</returns>
        public string ReadXmlFile(string argFileFullPathName, ref string argErrorMsg)
        {
            if (string.IsNullOrWhiteSpace(argFileFullPathName)) return string.Empty;
            try
            {    
                XmlDocument doc = new XmlDocument();
                string strExtensionName = Path.GetExtension(argFileFullPathName);
                if (!strExtensionName.EndsWith("xml", StringComparison.OrdinalIgnoreCase))
                {
                    argFileFullPathName = string.Concat(argFileFullPathName, ".xml");
                }
                doc.Load(argFileFullPathName);
                if (doc.InnerXml == null) { argErrorMsg = "读取XML文件失败"; }
                return doc?.InnerXml ?? string.Empty;
            }
            catch (Exception ep)
            {
                argErrorMsg = "读取XML文件异常：" + ep.Message;
                return string.Empty;
            }
        }

        /// <summary>
        /// 读取XML文件
        /// </summary>
        /// <typeparam name="T">泛型类</typeparam>
        /// <param name="argFileFullPathName">文件绝对全路径名称（可带后缀）</param>
        /// <returns>返回泛型对象</returns>
        public T? ReadXmlFileStream<T>(string argFileFullPathName) where T : class
        {
            if (string.IsNullOrWhiteSpace(argFileFullPathName)) return null; 
            try
            {
                string strExtensionName = Path.GetExtension(argFileFullPathName);
                if (!strExtensionName.EndsWith("xml", StringComparison.OrdinalIgnoreCase))
                {
                    argFileFullPathName = string.Concat(argFileFullPathName, ".xml");
                }
                string? strFileFullPath = Path.GetDirectoryName(argFileFullPathName);
                if (string.IsNullOrEmpty(strFileFullPath)) return null;
                FileStream ReadStream = new FileStream(argFileFullPathName, FileMode.Open, FileAccess.Read);
                if (ReadStream != null)
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T)); //xml对象
                    if (serializer != null)
                    {
                        return serializer.Deserialize(ReadStream) as T;
                    }
                    ReadStream.Close();
                    ReadStream.Dispose();
                }
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}
